package com.ruibang.glass.purchase.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.GlobalUser;
import com.ruibang.glass.common.domain.file.FileBusiness;
import com.ruibang.glass.purchase.constant.PurchaseErrorCode;
import com.ruibang.glass.purchase.domain.req.PurchaseOrderReq;
import com.ruibang.glass.purchase.entity.*;
import com.ruibang.glass.purchase.feign.FileApi;
import com.ruibang.glass.purchase.mapper.PurchaseArrivalProductMapper;
import com.ruibang.glass.purchase.mapper.PurchaseContractsMapper;
import com.ruibang.glass.purchase.mapper.PurchaseOrderDetailsMapper;
import com.ruibang.glass.purchase.mapper.PurchaseRelatedProductMapper;
import com.ruibang.glass.purchase.service.CommonService;
import com.ruibang.glass.purchase.service.PurchaseArrivalOrdersService;
import com.ruibang.glass.purchase.service.PurchaseOrderDetailsService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 采购订单详情表 服务实现类
 * </p>
 *
 * @author mameng
 * @since 2024-03-28
 */
@Service
public class PurchaseOrderDetailsServiceImpl extends ServiceImpl<PurchaseOrderDetailsMapper, PurchaseOrderDetails> implements PurchaseOrderDetailsService {

    @Autowired
    private PurchaseRelatedProductMapper purchaseRelatedProductMapper;

    @Autowired
    private FileApi fileApi;

    @Autowired
    private PurchaseArrivalOrdersService purchaseArrivalOrdersService;

    @Autowired
    private PurchaseArrivalProductMapper purchaseArrivalProductMapper;

    @Autowired
    private RedisSingleService redisService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private PurchaseContractsMapper purchaseContractsMapper;

    @Override
    public IPage<PurchaseOrderDetails> getPage(PurchaseOrderReq purchaseReportReq) {
        IPage<PurchaseOrderDetails> page = baseMapper.getPage(new Page<>(purchaseReportReq.getPageNo(), purchaseReportReq.getPageSize()), purchaseReportReq);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePurchaseOrderDetails(PurchaseOrderDetails purchaseOrderDetails) {
        baseMapper.updateById(purchaseOrderDetails);
        fileApi.deleteByBusinessId(purchaseOrderDetails.getId());
        if (CollectionUtils.isNotEmpty(purchaseOrderDetails.getFileIdList())) {
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setBusinessId(purchaseOrderDetails.getId());
            fileBusiness.setFileIds(purchaseOrderDetails.getFileIdList());
            fileApi.updateBusinessById(fileBusiness);
        }
        purchaseRelatedProductMapper.delete(Wrappers.<PurchaseRelatedProduct>lambdaQuery().eq(PurchaseRelatedProduct::getDetailId, purchaseOrderDetails.getId()));
        for (PurchaseRelatedProduct purchaseRelatedProduct : purchaseOrderDetails.getPurchaseRelatedProductList()) {
            purchaseRelatedProduct.setDetailId(purchaseOrderDetails.getId());
            purchaseRelatedProductMapper.insert(purchaseRelatedProduct);
        }

    }


    @Override
    public PurchaseOrderDetails getPurchaseOrderDetails(String id) {
        PurchaseOrderDetails orderDetails = baseMapper.selectById(id);
        if(orderDetails!=null) {
            Object userNameObj = redisService.hget(RedisKey.USER_GROUP_TYPE, orderDetails.getAcceptor());
            if (userNameObj != null) {
                orderDetails.setAcceptorName(userNameObj.toString());
            }
            ResultBody<List<String>> fileIdsByBusinessId = fileApi.getFileIdsByBusinessId(id);
            if (fileIdsByBusinessId != null) {
                orderDetails.setFileIdList(fileIdsByBusinessId.getData());
            }
            List<PurchaseRelatedProduct> list1 = purchaseRelatedProductMapper.selectList(Wrappers.<PurchaseRelatedProduct>lambdaQuery()
                    .eq(PurchaseRelatedProduct::getDetailId, id));
            orderDetails.setPurchaseRelatedProductList(list1);

            List<PurchaseContracts> contracts = purchaseContractsMapper.selectList(Wrappers.<PurchaseContracts>lambdaQuery().eq(PurchaseContracts::getContractNumber,orderDetails.getContractNumber()));
            if(CollectionUtils.isNotEmpty(contracts)){
                PurchaseContracts contract = contracts.get(0);
                orderDetails.setReceiverPhone(contract.getReceiverPhone());
            }
        }
        return orderDetails;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody addPurchaseArrOrder(PurchaseOrderDetails purchaseOrderDetails) {
        if (CollectionUtils.isEmpty(purchaseOrderDetails.getPurchaseRelatedProductList())) {
            throw new ServiceException(PurchaseErrorCode.ARRIVAL_NO_PRODUCT.getCode(), PurchaseErrorCode.ARRIVAL_NO_PRODUCT.getMsg());
        }
        Map<Object, Object> userMap = redisService.hmget(RedisKey.USER_GROUP_TYPE);
        PurchaseArrivalOrders purchaseArrivalOrders = new PurchaseArrivalOrders();
        BeanUtils.copyProperties(purchaseOrderDetails, purchaseArrivalOrders);
        purchaseArrivalOrders.setPurchaseOrderNumber(purchaseOrderDetails.getPurchaseOrderNumber());
        purchaseArrivalOrders.setPurchaseArrivalOrderNumber(purchaseArrivalOrdersService.getArrivalOrderNumber());
        purchaseArrivalOrders.setProjectNumber(purchaseOrderDetails.getProjectNumber());
        purchaseArrivalOrders.setCreationTime(LocalDateTime.now());
        purchaseArrivalOrders.setStatus(CommonConstant.ONE_STR);
        GlobalUser user = commonService.getUser();
        if(user!=null){
            purchaseArrivalOrders.setArrivalConfirmUser(user.getName());
            purchaseArrivalOrders.setArrivalConfirmUserId(user.getUserId());
        }
        purchaseArrivalOrders.setInspector(userMap.get(purchaseOrderDetails.getApplicantId())==null?null:userMap.get(purchaseOrderDetails.getApplicantId()).toString());
        purchaseArrivalOrders.setInspectorId(purchaseOrderDetails.getApplicantId());
        purchaseArrivalOrders.setId(null);
        purchaseArrivalOrdersService.save(purchaseArrivalOrders);
        List<PurchaseRelatedProduct> oldProductList = purchaseRelatedProductMapper.selectList(Wrappers.<PurchaseRelatedProduct>lambdaQuery().eq(PurchaseRelatedProduct::getDetailId,purchaseOrderDetails.getId()));
        Map<String,PurchaseRelatedProduct> oldProductMap = null;
        double old = 0;
        if(CollectionUtils.isNotEmpty(oldProductList)){
            for (PurchaseRelatedProduct product : oldProductList) {
                if(product.getQuantity()!=null){
                    old = old + product.getQuantity();
                }
            }
            oldProductMap = oldProductList.stream().collect(Collectors.toMap(PurchaseRelatedProduct::getId,p->p,(p1,p2)->p1));
        }
        List<PurchaseRelatedProduct> purchaseRelatedProductList = purchaseOrderDetails.getPurchaseRelatedProductList();
        double newNum = 0;
        List<PurchaseRelatedProduct> newProducts = new ArrayList<>();
        for (PurchaseRelatedProduct purchaseRelatedProduct : purchaseRelatedProductList) {
            if(purchaseRelatedProduct.getQuantity()==null||purchaseRelatedProduct.getQuantity()==0) continue;
            PurchaseRelatedProduct oldProduct = oldProductMap.get(purchaseRelatedProduct.getId());
            if (purchaseRelatedProduct.getQuantity() != null && purchaseRelatedProduct.getQuantity()>0) {
                double quantity = oldProduct.getQuantity()-purchaseRelatedProduct.getQuantity();
                if(quantity<0) quantity = 0;
                oldProduct.setQuantity(quantity);
                newProducts.add(oldProduct);
                newNum = newNum + purchaseRelatedProduct.getQuantity();
            }
            PurchaseArrivalProduct purchaseArrivalProduct = new PurchaseArrivalProduct();
            BeanUtils.copyProperties(purchaseRelatedProduct, purchaseArrivalProduct);
            purchaseArrivalProduct.setId(null);
            purchaseArrivalProduct.setOrderItemId(purchaseRelatedProduct.getId());
            purchaseArrivalProduct.setSaleArrivalId(purchaseArrivalOrders.getId());
            purchaseArrivalProductMapper.insert(purchaseArrivalProduct);
        }

        if(CollectionUtils.isNotEmpty(newProducts)){
            purchaseRelatedProductMapper.updateBatch(newProducts,1000);
        }

        if(newNum == 0){
            purchaseOrderDetails.setOrderStatus(CommonConstant.ONE_STR);
            purchaseOrderDetails.setOverStatus(Constants.ZERO_STR);
        }else if(old == newNum){
            purchaseOrderDetails.setOrderStatus(CommonConstant.THREE_STR);
            purchaseOrderDetails.setOverStatus(Constants.ONE_STR);
        }else if(old > newNum){
            purchaseOrderDetails.setOrderStatus(CommonConstant.TWO_STR);
            purchaseOrderDetails.setOverStatus(Constants.ZERO_STR);
        }
        baseMapper.updateById(purchaseOrderDetails);
        return ResultBody.success();
    }

    @Override
    public void updatePayStatus(PurchaseOrderDetails purchaseOrderDetails) {
        PurchaseOrderDetails purchaseOrderDetails1 = baseMapper.selectById(purchaseOrderDetails.getId());
        purchaseOrderDetails1.setPayStatus(purchaseOrderDetails.getPayStatus());
        baseMapper.updateById(purchaseOrderDetails1);
    }

    @Override
    public void updateOverStatus(PurchaseOrderDetails purchaseOrderDetails) {
        PurchaseOrderDetails purchaseOrderDetails1 = baseMapper.selectById(purchaseOrderDetails.getId());
        purchaseOrderDetails1.setOverStatus(purchaseOrderDetails.getOverStatus());
        baseMapper.updateById(purchaseOrderDetails1);
    }
}
